package blog

import (
	"encoding/json"
	"time"
	"vblog/common"
)

func NewBlogSet() *BlogSet {
	return &BlogSet{
		Items: []*Blog{},
	}
}

type BlogSet struct {
	// 总共多少个文章
	Total int64   `json:"total"`
	Items []*Blog `json:"items"`
}

func (s *BlogSet) String() string {
	//
	dataJson, _ := json.MarshalIndent(s, "", "  ")
	return string(dataJson)
}

// blog的构造函数
// 为什么使用构造函数? 不直接使用结构体?
// 不使用构造函数,后面如果blog的结构体新加属性,
// 那么每个使用blog对象的地方都需要重新添加属性,会很麻烦.
// 所以使用构造函数保证兼容性: 把需要初始化的 在这个函数初始化,
// 有需要默认置的, 补充默认值
func NewBlog(req *CreateBlogRequest) *Blog {
	return &Blog{
		Meta:              NewMeta(),
		CreateBlogRequest: req,
	}
}
func (b *Blog) String() string {
	//
	dataJson, _ := json.MarshalIndent(b, "", "  ")
	return string(dataJson)
}

// 通过组合,匿名嵌套来产生一个新的结构体,新的对象
type Blog struct {
	*Meta
	*CreateBlogRequest
}

//	type Tabler interface {
//		TableName() string
//	}
//
// 定义Gorm 存入数据是表的名字
func (b *Blog) TableName() string {
	return "blogs"
}

// 定义Meta的构造函数
func NewMeta() *Meta {
	return &Meta{
		CreatedAt: time.Now().Unix(),
	}
}

type Meta struct {
	Id int `json:"id"`

	//后段直接存储时间辍,当需要展示的时候由前段(web,app)负责带上用户的当前时区作展示.
	CreatedAt   int64 `json:"created_at"`
	UpdatedAt   int64 `json:"updated_at"`
	PublishedAt int64 `json:"published_at"`
}

func NewCreateBlogRequest() *CreateBlogRequest {
	return &CreateBlogRequest{
		Tags:   map[string]string{},
		Status: STATUS_DRAFT,
	}
}

type CreateBlogRequest struct {
	Title   string `json:"title" gorm:"column:title" validate:"required"`
	Author  string `json:"author" gorm:"column:author" validate:"required"`
	Content string `json:"content" validate:"required"`
	// gorm 不知道map怎么存到数据库中
	// 通过标签"gorm:"serializer:json""直接存成json
	Tags map[string]string `json:"tags" gorm:"serializer:json"`
	//文章状态
	Status STATUS `json:"status"`
}

// 使用一个第三方校验库检查参数是否合法
// 使用这个库来做校验https://github.com/go-playground/validator
func (req *CreateBlogRequest) Validate() error {
	// 自定义校验
	// if req.Title == ""{
	// 	err := fmt.Errorf("title not nil")
	// 	return err
	// }
	// 为了其他地方使用,将validator实例做成一个全局对象:校验器
	// v := validator.New()
	// 校验规则通过写Struct
	return common.Validate(req)
}
